package analyse;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.springframework.util.Assert;

import spring.SpringApplicationCtx;
import util.TimeUtil;

import com.stock.StockQuery;
import com.stock.dao.Buysave;
import com.stock.dao.BuysaveDAO;
import com.stock.dao.Stockanlyz;
import com.stock.dao.StockanlyzDAO;
import com.stock.dao.Stockdaydeal;

import data.Constant;
import data.DataBuffer;
import data.LoadData;
import data.TimeStock;

public class RecommandOnTime extends Thread{

	private LinkedHashSet<String> weakPirceCode = new LinkedHashSet<String>();
	private LinkedHashSet<String> lowPirceCode = new LinkedHashSet<String>();
	private StockanlyzDAO dao = (StockanlyzDAO) SpringApplicationCtx.getCtx().getBean("StockanlyzDAO");
	private LinkedHashSet<String> selectPool = new LinkedHashSet<String>();
	
	public RecommandOnTime() {
	}
	
	@Override
	public void run() {
		
		setTimeStock30Aver();
		initPool();
		highAlazy();
		weakAlazy();
		IndustrySort is = new IndustrySort();
		SinaIndustrySort sis = new SinaIndustrySort();
		averLineAlazy();
		
		while(true){
			verPriceAlazy();
			is.sort();
			DataBuffer.setIndustryOrder(is.getRateSort());
			DataBuffer.setSinaIndustryOrder(sis.getResult());
			
			bigDeal();
			
			speedAlazy();
			
			select();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	private void bigDeal(){
		DataBuffer.getBigdeal().clear();
		Assert.isTrue(DataBuffer.getBigdeal().isEmpty());
		
		BigDecimal shBat = LoadData.getTimeStock("sh000001").getAmount()
				.divide(LoadData.getTimeStock("sh000001").getLastStock().getAmount(), 2,
						BigDecimal.ROUND_HALF_UP);
		for (TimeStock ts : LoadData.getStockList().values()) {
			if(ts.getLastStock()!=null&&ts.getLastStock().getAmount().compareTo(BigDecimal.ZERO)>0){
				if(ts.getAmount()
						.divide(ts.getLastStock().getAmount(), 2,
								BigDecimal.ROUND_HALF_UP)
								.compareTo(shBat.multiply(new BigDecimal(1.8)))>0
								&&ts.getRatePercent().compareTo(BigDecimal.ZERO)>0){
					DataBuffer.getBigdeal().add(ts.getCode());
				}
			}
		}
	}
	
	private void setInfo(String number,int info) {
		if(LoadData.getTimeStock(number)!=null){
			LoadData.getTimeStock(number).setInfo(info);
		}
	}
	
	private void highAlazy(){
		String sql = "from Stockdaydeal where number=:number order by dealDay desc";
		
		StockQuery stockQuery = (StockQuery) SpringApplicationCtx.getCtx().getBean("StockQuery");
		List<Stockanlyz> highprices =dao.findByPriceLevel(1);
		for (Stockanlyz stockanlyz : highprices) {
			Query query = stockQuery.getCurrentSession().createQuery(sql);
			List<Stockdaydeal> stockdaydeals = 
					query.setMaxResults(60).setString("number", stockanlyz.getNumber()).list();
			if(stockdaydeals.size()<60){
				continue;
			}
			
			Stockdaydeal maxStockdaydeal = stockdaydeals.get(stockanlyz.getMaxToDays());
			if(maxStockdaydeal.getAmountBat().compareTo(Constant.THREE)>0
					&&maxStockdaydeal.getPrice().subtract(maxStockdaydeal.getBeginPrice()).multiply(Constant.ONEHUNDRED)
					.divide(maxStockdaydeal.getPredayprice(), 2,BigDecimal.ROUND_HALF_UP).compareTo(Constant.NEGTHREE)<0){
				setInfo(stockanlyz.getNumber(),-1);
			}
			//超量
			if(maxStockdaydeal.getAmount().divide(stockanlyz.getAverAmount(),2,BigDecimal.ROUND_HALF_UP).compareTo(Constant.EIGHT)>0){
				setInfo(stockanlyz.getNumber(),-1);
			}
			
			for (int i = stockanlyz.getMaxToDays(); i>=0; i--) {
				Stockdaydeal stockdaydeal = stockdaydeals.get(i);
				if(stockdaydeal.getRatepercent().compareTo(Constant.NEGSIX)<0){
					setInfo(stockanlyz.getNumber(),-1);
				}
			}
			
			for (int i = stockanlyz.getMaxToDays(); i>=2; i--) {
				Stockdaydeal first = stockdaydeals.get(i);
				Stockdaydeal second = stockdaydeals.get(i-1);
				Stockdaydeal third = stockdaydeals.get(i-2);
				
				boolean c1 = false;
				boolean c2 = false;
				boolean c3 = false;
				
				c1=first.getRatepercent().compareTo(Constant.ZERO)>0;
				c2=second.getMaxPrice().subtract(second.getPrice()).multiply(Constant.ONEHUNDRED)
						.divide(second.getPredayprice(),2,BigDecimal.ROUND_HALF_UP).compareTo(Constant.TWO)>0 //避雷针
						||second.getMaxPrice().add(second.getMinPrice()).multiply(Constant.ONEHUNDRED).divide(Constant.TWO,2,BigDecimal.ROUND_HALF_UP)
						.compareTo(Constant.ASZERO)<=0 //十字架
						||second.getPrice().compareTo(second.getBeginPrice())<0;//阴线
				c3 = third.getRatepercent().compareTo(Constant.NEGASZERO)<0
						||third.getPrice().compareTo(third.getBeginPrice())<0;
				if(c1&&c2&&c3){
					setInfo(first.getNumber(),-1);
				}
				if(c1&&second.getPrice().compareTo(first.getBeginPrice())<0&&third.getPrice().compareTo(third.getBeginPrice())<0){
					setInfo(first.getNumber(),-1);
				}
			}
			if(LoadData.getTimeStock(stockanlyz.getNumber())!=null&&LoadData.getTimeStock(stockanlyz.getNumber()).getInfo()>-1){
				DataBuffer.getHighPirceCode().add(stockanlyz.getNumber());
			}
		}
	}
	
	private void weakAlazy(){
		String sql = "from Stockdaydeal where number=:number order by dealDay desc";
		
		StockanlyzDAO dao = (StockanlyzDAO) SpringApplicationCtx.getCtx().getBean("StockanlyzDAO");
		StockQuery stockQuery = (StockQuery) SpringApplicationCtx.getCtx().getBean("StockQuery");
		List<Stockanlyz> lowprices =dao.findByPriceLevel(-1);
		
		for (Stockanlyz stockanlyz : lowprices) {
			Query query = stockQuery.getCurrentSession().createQuery(sql);
			List<Stockdaydeal> stockdaydeals = 
					query.setMaxResults(20).setString("number", stockanlyz.getNumber()).list();
			if(stockdaydeals.size()<20){
				continue;
			}
			
			boolean weak = true;
			
			for (Stockdaydeal s : stockdaydeals) {
				if(s.getRatepercent().compareTo(Constant.THREE)>0){
					weak = false;
					break;
				}
			}
			if(weak){
				weakPirceCode.add(stockanlyz.getNumber());
			}
		}
		weakPirceCode.remove("sz399001");
		weakPirceCode.remove("sh000001");
		
		List<Stockanlyz> lowprices2 =dao.findByMinToDays(0);
		for (Stockanlyz stockanlyz : lowprices2) {
			lowPirceCode.add(stockanlyz.getNumber());
		}
	}
	
	private void lowAlazy(){
		for (String code : lowPirceCode) {
			TimeStock ts = LoadData.getTimeStock(code);
			if(ts.getRatePercent().compareTo(BigDecimal.ZERO)>0&&ts.getCurPrice().subtract(ts.getMinPrice()).multiply(Constant.ONEHUNDRED)
					.divide(ts.getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP).compareTo(Constant.THREE)>0&&isPriceGood(code)){
				ts.selected();
				ts.setMark("底部上涨");
				DataBuffer.getFinalSel().add(code);
				/*BuysaveDAO buysaveDAO = (BuysaveDAO)SpringApplicationCtx.getCtx().getBean("BuysaveDAO");
				if(buysaveDAO.findByNumber(code).isEmpty()){
					Buysave bs = new Buysave();
					bs.setUserName("bottomUP");
					bs.setBuyAmount(ts.getCurPrice());
					bs.setBuyDate(ts.getDate());
					bs.setBuyTime(ts.getTime());
					bs.setNumber(code);
					bs.setBuyPrice(ts.getCurPrice());
					bs.setBuyQty(1);
					bs.setOwnAmount(ts.getCurPrice());
					bs.setOwnQty(1);
					buysaveDAO.save(bs);
				}*/
			}
		}
	}
	
	private void averLineAlazy(){
		List<Stockanlyz> list = dao.findByProperty("averlineUp", true);
		for (Stockanlyz stockanlyz : list) {
			DataBuffer.getUpline().add(stockanlyz.getNumber());
		}
	}
	
	private void speedAlazy(){
//		DataBuffer.getSpeedUp().clear();
//		Assert.isTrue(DataBuffer.getSpeedUp().isEmpty());
		
		for (String code : selectPool) {
			TimeStock ts = LoadData.getTimeStock(code);
			if(ts.getPriceWive().compareTo(BigDecimal.ONE)>=0
					&&ts.getMaxPrice().subtract(ts.getCurPrice()).multiply(Constant.ONEHUNDRED).divide(ts.getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP).compareTo(new BigDecimal("0.1"))<0){
				DataBuffer.getSpeedUp().add(code);
			}
			
		}
	}
	
	private void select(){
		BigDecimal shAmountBat = LoadData.getTimeStock("sh000001").getAmountBat();
		BigDecimal szAmountBat = LoadData.getTimeStock("sz399001").getAmountBat();
		BuysaveDAO buysaveDAO = (BuysaveDAO)SpringApplicationCtx.getCtx().getBean("BuysaveDAO");
		for (String code : selectPool) {
			TimeStock ts = LoadData.getTimeStock(code);
			if(ts.getRatePercent().compareTo(Constant.EIGHT)>0){
//				selectPool.remove(code);
			}else if(ts.isHead()&&isPriceGood(code)){
				if(ts.getMinPrice().subtract(ts.getPreDayPrice()).multiply(Constant.ONEHUNDRED).divide(ts.getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP).compareTo(Constant.NEGTHREE)<0){
					continue;
				}
				boolean dealBat = false;
				if(code.indexOf("h")>0){
					dealBat = ts.getAmountBat().compareTo(shAmountBat)>0;
				}else{
					dealBat = ts.getAmountBat().compareTo(szAmountBat)>0;
				}
				if((DataBuffer.getSpeedUp().contains(code)&&(ts.getAmountBat().compareTo(BigDecimal.ZERO)==0||dealBat))
						||(DataBuffer.getLowUP().contains(code)&&DataBuffer.getBigdeal().contains(code))){
					ts.selected();
					ts.setMark("涨幅居前");
					if(DataBuffer.getVerLine().contains(code)){
						ts.setMark("均线+涨幅居前");
					}
					DataBuffer.getFinalSel().add(code);
					/*if(buysaveDAO.findByNumber(code).isEmpty()){
						Buysave bs = new Buysave();
						bs.setUserName("headrun");
						bs.setBuyAmount(ts.getCurPrice());
						bs.setBuyDate(ts.getDate());
						bs.setBuyTime(ts.getTime());
						bs.setNumber(code);
						bs.setBuyPrice(ts.getCurPrice());
						bs.setBuyQty(1);
						bs.setOwnAmount(ts.getCurPrice());
						bs.setOwnQty(1);
						buysaveDAO.save(bs);
					}*/
				}
			}
			
		}
		
		for (String code : weakPirceCode) {
			TimeStock ts = LoadData.getTimeStock(code);
			if(ts.getRatePercent().compareTo(Constant.FOUR)>0&&ts.getAmountBat().compareTo(new BigDecimal("1.8"))>0&&isPriceGood(code)){
				DataBuffer.addLowUP(code);
				ts.selected();
				DataBuffer.getFinalSel().add(code);
				ts.setMark("弱势上涨+量增");
				/*if(buysaveDAO.findByNumber(code).isEmpty()){
					Buysave bs = new Buysave();
					bs.setUserName("lowUP");
					bs.setBuyAmount(ts.getCurPrice());
					bs.setBuyDate(ts.getDate());
					bs.setBuyTime(ts.getTime());
					bs.setNumber(code);
					bs.setBuyPrice(ts.getCurPrice());
					bs.setBuyQty(1);
					bs.setOwnAmount(ts.getCurPrice());
					bs.setOwnQty(1);
					buysaveDAO.save(bs);
				}*/
			}
		}
		
		lowAlazy();
		
		verPriceSelect();
		
		LinkedHashSet<String> curHighDown = new LinkedHashSet<String>();
		for (String code : DataBuffer.getFinalSel()) {
			if(!isPriceGood(code)){
				curHighDown.add(code);
			}
		}
		DataBuffer.getFinalSel().removeAll(curHighDown);
	}
	
	private boolean isPriceGood(String code){
		TimeStock ts = LoadData.getTimeStock(code);
		BigDecimal topDiff = ts.getMaxPrice().subtract(ts.getCurPrice()).multiply(Constant.ONEHUNDRED).divide(ts.getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP);
		//上影线
		if(topDiff.compareTo(new BigDecimal("1.8"))>0&&ts.getRatePercent().compareTo(Constant.FOUR)<0){
			return false;
		}
		
		/*if(ts.getRatePercent().compareTo(Constant.EIGHT)>0){
			return false;
		}*/
		
		if(ts.getCurPrice().compareTo(ts.getAver30())<0
				&&ts.getAver30().subtract(ts.getPreDayPrice()).multiply(Constant.ONEHUNDRED).divide(ts.getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP).compareTo(Constant.EIGHT)<0){
			return false;
		}
		
		return true;
	}
	
	private void initPool(){
		Set<String> set = LoadData.getStockList().keySet();
		for (String code : set) {
			TimeStock ts = LoadData.getTimeStock(code);
			
			if(ts.getLastStock()==null){
				selectPool.add(code);
				continue;
			}
			
			BigDecimal lastPercent = ts.getLastStock().getCurPrice().subtract(ts.getLastStock().getPreDayPrice()).multiply(Constant.ONEHUNDRED).divide(ts.getLastStock().getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP);
			boolean lastIsRed = ts.getLastStock().getCurPrice().compareTo(ts.getBeginPrice())>0;
			BigDecimal topDiff = ts.getLastStock().getMaxPrice().subtract(ts.getLastStock().getCurPrice()).multiply(Constant.ONEHUNDRED).divide(ts.getLastStock().getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP);
			//红体上影线
			if(lastIsRed&&topDiff.compareTo(new BigDecimal("1.8"))>0){
				continue;
			}
			
			BigDecimal aver30BotDiff = ts.getAver30().subtract(ts.getLastStock().getCurPrice()).multiply(Constant.ONEHUNDRED).divide(ts.getLastStock().getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP);
			
			if(ts.getLastStock().getBeginPrice().compareTo(ts.getAver30())>0&&aver30BotDiff.compareTo(new BigDecimal("1.8"))>0){
				continue;
			}
			
			selectPool.add(code);
			
		}
		selectPool.remove("sh000001");
		selectPool.remove("sz399001");
	}
	
	private void verPriceAlazy(){
		Set<String> set = LoadData.getStockList().keySet();
		for (String code : set) {
			TimeStock ts = LoadData.getTimeStock(code);
			BigDecimal diff = ts.getBeginPrice().subtract(ts.getAver30()).multiply(Constant.ONEHUNDRED).divide(ts.getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP).abs();
			if(diff.compareTo(new BigDecimal("0.2"))<0){
				DataBuffer.getVerLine().add(code);
			}
			BigDecimal diff2 = ts.getBeginPrice().subtract(ts.getAver20()).multiply(Constant.ONEHUNDRED).divide(ts.getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP).abs();
			if(diff2.compareTo(new BigDecimal("0.2"))<0){
				DataBuffer.getVerLine().add(code);
			}
			BigDecimal diff3 = ts.getBeginPrice().subtract(ts.getAver10()).multiply(Constant.ONEHUNDRED).divide(ts.getPreDayPrice(),2,BigDecimal.ROUND_HALF_UP).abs();
			if(diff3.compareTo(new BigDecimal("0.2"))<0){
				DataBuffer.getVerLine().add(code);
			}
		}
	}
	
	private void setTimeStock30Aver(){
		List<Stockanlyz> list = dao.findAll();
		for (Iterator iterator = list.iterator(); iterator.hasNext();) {
			Stockanlyz stockanlyz = (Stockanlyz) iterator.next();
			if(LoadData.getTimeStock(stockanlyz.getNumber())!=null&&stockanlyz.getThirtyDayPrice()!=null){
				LoadData.getTimeStock(stockanlyz.getNumber()).setAver30(stockanlyz.getThirtyDayPrice());
				LoadData.getTimeStock(stockanlyz.getNumber()).setAver20(stockanlyz.getTwentyDayPrice());
				LoadData.getTimeStock(stockanlyz.getNumber()).setAver10(stockanlyz.getTenDayPrice());
			}
		}
	}
	
	private void verPriceSelect(){
		for (String code : DataBuffer.getVerLine()) {
			if(DataBuffer.getUpline().contains(code)){
				TimeStock ts = LoadData.getTimeStock(code);
				if((ts.getBeginPrice().compareTo(ts.getAver30())<0||ts.getMinPrice().compareTo(ts.getAver30())<0)&&ts.getCurPrice().compareTo(ts.getAver30())>0){
					ts.selected();
					ts.setMark("30日均线上涨");
					DataBuffer.getFinalSel().add(code);
				}
				if((ts.getBeginPrice().compareTo(ts.getAver20())<0||ts.getMinPrice().compareTo(ts.getAver20())<0)&&ts.getCurPrice().compareTo(ts.getAver20())>0){
					ts.selected();
					ts.setMark("20日均线上涨");
					DataBuffer.getFinalSel().add(code);
				}
				if((ts.getBeginPrice().compareTo(ts.getAver20())<0||ts.getMinPrice().compareTo(ts.getAver20())<0)&&ts.getCurPrice().compareTo(ts.getAver20())>0){
					ts.selected();
					ts.setMark("10日均线上涨");
					DataBuffer.getFinalSel().add(code);
				}
			}
		}
	}
}
